package nzb;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import jobs.DownloadStatus;
import play.Logger;
import play.Play;
import play.cache.Cache;
import yenc.YDecoder;
import controllers.NzbGrabber;

public class FileDownloader {
	public static boolean	isDownloading = false;
	
	public NzbFile 			currentFile;
	public BufferedWriter 	segmentBuffer;
	
	public YDecoder		  	yDecoder;
	
	public BufferedReader 	segmentDownloaded;
	
	public String 			currentSegmentBuffer;
	
	public 	List<Segment>	segmentsList;
	public  ConcurrentLinkedQueue<SegmentDownloader> segmentsDownloaderQueue;
	
	public static String	DOWNLOAD_CACHE_DIR	= Play.configuration.get("download_cachedir").toString();
	public static String	DOWNLOAD_DEST_DIR	= Play.configuration.get("download_destinationdir").toString();
	public static Integer	NNTP_PORT 			= Integer.parseInt(Play.configuration.get("nntp_port").toString());
	public static String	NNTP_HOST 			= Play.configuration.get("nntp_host").toString();
	public static String	NNTP_USER 			= Play.configuration.get("nntp_user").toString();
	public static String	NNTP_PASS 			= Play.configuration.get("nntp_pass").toString();
	
	public 	NzbGrabber		nzbGrabber;
	
	public FileDownloader(NzbGrabber nzbGrabber, NzbFile currentFile) throws IOException
	{
		this.nzbGrabber = nzbGrabber;
		this.currentFile = currentFile;
		this.segmentsDownloaderQueue = new ConcurrentLinkedQueue<SegmentDownloader>();
		this.segmentsList = new ArrayList<Segment>();
	}

	public DownloadStatus getDlStatus() {
		return (DownloadStatus) Cache.get("DOWNLOAD_STATUS");
	}
	
	public void run() {
		try {
			getDlStatus().setCurrentFileName(currentFile.getFileName());
			getDlStatus().getFilesStatus().put(currentFile.getFileName(), new Integer[2]);
			getDlStatus().getFilesStatus().get(currentFile.getFileName())[DownloadStatus.CURRENT_SEGMENTS] = 0;
			String group = currentFile.getGroups().get(0);
			
			segmentsList = currentFile.getSegments();
			
			for (Segment currentSegment : segmentsList) {
				this.segmentsDownloaderQueue.add(new SegmentDownloader(currentSegment, group, currentFile.getFileName()));
			}
			getDlStatus().getFilesStatus().get(currentFile.getFileName())[DownloadStatus.TOTAL_SEGMENTS] = segmentsList.size();
			
			ExecutorService	executor = Executors.newFixedThreadPool(20);
			
			for (SegmentDownloader segmentDownloader : this.segmentsDownloaderQueue) {
					executor.submit(segmentDownloader);
			}
			
			executor.shutdown();
			executor.awaitTermination(1, TimeUnit.HOURS);
			
			Logger.info("Fin du FileDownloader : " + this.currentFile.getFileName());
			
			this.segmentsList.clear();
			getDlStatus().setFilesCount(getDlStatus().getFilesCount() + 1);
		} catch (Exception e) {
			Logger.error("Error lors du telechargement d'un segement ", e);
			e.printStackTrace();
		}
	}
	
	private void clearSegmentsFiles()
	{
	    System.out.println("Suppression des segments de fichier :" + currentFile.getFileName() + "...");
		Iterator<Segment> segmentsIterator = segmentsList.iterator();
		File currentSegmentFile = null;
		while (segmentsIterator.hasNext()) {
			currentSegmentFile = new File(DOWNLOAD_CACHE_DIR + segmentsIterator.next().getId());
			currentSegmentFile.delete();
		}
		currentSegmentFile = null;
	}
}
